from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.service import Service
from selenium.common.exceptions import TimeoutException
import json
from time import sleep
import os
import re
import platform

"""
    打开浏览器
    写入cookie
    设置代理=后续开发
    打开需要的页面------最后
"""


class BrowserManager:
	# 初始化，生成浏览器对象
	def __init__(self, cookie=None, is_headless=1, target_type=0, proxy=None):
		"""
		初始化BrowserManager实例。
		参数:
			cookie (str): cookies的JSON字符串，默认值为None。如果为None，则不加载cookies。
			is_headless (int): 是否启用无头模式，1表示启用，0表示不启用。
			target_type (int): 0表示百度首页，1表示VIP文档，2表示原力任务。
			proxy (str): IP代理地址，默认值为None。如果为None，则不使用代理。
		"""
		self.cookies = json.loads(cookie) if cookie else None
		self.is_headless = is_headless
		self.target_type = target_type
		self.proxy = proxy
		self.driver = self._initialize_driver()
		sleep(1)
		handles = self.switch_to_new_tab()
		sleep(1)
		self.driver.get("https://www.baidu.com")
		self.close_other_tabs(handles)
		# 初始化完成，打开了百度首页
		sleep(1)
		# 如果有cookie，写入cookie。
		if self.cookies:
			self.add_cookies()
		# 跳转到指定页面
		self.go_target_url()

	def _initialize_driver(self):
		"""
		初始化Chrome WebDriver。
		返回:
			webdriver.Chrome: 初始化后的Chrome WebDriver实例。
		"""
		chrome_options = Options()
		chrome_options.add_argument("--disable-blink-features=AutomationControlled")
		chrome_options.add_experimental_option("useAutomationExtension", False)
		chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
		if self.is_headless:
			chrome_options.add_argument("window-size=1920,1080")
			chrome_options.add_argument('--disable-blink-features')
			chrome_options.add_argument('--disable-blink-features=AutomationControlled')
			chrome_options.add_argument('--incognito')
			chrome_options.add_argument('--disable-gpu')  # 禁用GPU加速
			chrome_options.add_argument('--no-sandbox')  # 非沙盒模式
			chrome_options.add_argument('--disable-dev-shm-usage')  # 禁用/dev/shm
			chrome_options.add_argument('--disable-blink-features=AutomationControlled')  # 隐藏自动化特征
			chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])  # 隐藏自动化特征
			chrome_options.add_experimental_option("useAutomationExtension", False)
		else:
			chrome_options.add_argument("--start-maximized")
		chrome_options.add_argument("--lang=zh-CN")
		chrome_options.add_argument(
			"user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
		if self.is_headless == 1:
			chrome_options.add_argument("--headless")

		if self.proxy:
			chrome_options.add_argument(f'--proxy-server={self.proxy}')
		# 浏览器驱动器路径
		chrome_driver_path1 = os.path.join(os.path.dirname(os.path.dirname(__file__)), "static", 'chromedriver.exe')
		chrome_driver_path2 = os.path.join(os.path.dirname(os.path.dirname(__file__)), "static", 'chromedriver')
		# print(chrome_driver_path)
		server1 = Service(chrome_driver_path1)
		server2 = Service(chrome_driver_path2)

		# 判断系统类型选择浏览器驱动
		os_type = platform.system()
		# print(os_type)
		driver = None
		if os_type == 'Darwin':  # Darwin 是 Mac OS X 的系统名称
			# print(os_type)
			driver = webdriver.Chrome(options=chrome_options, service=server2)
		elif os_type == 'Windows':
			driver = webdriver.Chrome(options=chrome_options, service=server1)
		else:
			driver = webdriver.Chrome(options=chrome_options)

		driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
			"source": """
                    Object.defineProperty(navigator, 'webdriver', {
                        get: () => undefined
                    });
                    window.navigator.chrome = {
                        runtime: {},
                    };
                    Object.defineProperty(navigator, 'languages', {
                        get: () => ['zh-CN', 'zh']
                    });
                    Object.defineProperty(navigator, 'plugins', {
                        get: () => [1, 2, 3,4,5]
                    });
                """
		})
		# # 打印IP地址
		# ip_element = driver.find_element_by_xpath('//body')
		# print("当前IP地址:", ip_element.text)
		stealth_js_path = os.path.join(os.path.dirname(__file__), 'stealth.min.js')
		if os.path.exists(stealth_js_path):
			with open(stealth_js_path) as f:
				js = f.read()
			driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {"source": js})
		else:
			print(f"Stealth script file not found at {stealth_js_path}")
		# 初始化浏览器
		return driver

	def _initialize_driver1(self):
		"""
		初始化Chrome WebDriver。
		返回:
			webdriver.Chrome: 初始化后的Chrome WebDriver实例。
		"""
		chrome_options = Options()
		chrome_options.add_argument('--disable-blink-features')
		chrome_options.add_argument('--disable-blink-features=AutomationControlled')
		chrome_options.add_argument('--incognito')
		chrome_options.add_argument('--disable-gpu')  # 禁用GPU加速
		chrome_options.add_argument('--no-sandbox')  # 非沙盒模式
		chrome_options.add_argument('--disable-dev-shm-usage')  # 禁用/dev/shm
		chrome_options.add_argument('--disable-blink-features=AutomationControlled')  # 隐藏自动化特征
		chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])  # 隐藏自动化特征
		chrome_options.add_experimental_option("useAutomationExtension", False)
		if self.is_headless:
			chrome_options.add_argument("window-size=1920,1080")
		else:
			chrome_options.add_argument("--start-maximized")
		chrome_options.add_argument("--lang=zh-CN")
		chrome_options.add_argument(
			"user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
		# if self.is_headless == 1:
		# 	chrome_options.add_argument("--headless")
		if self.proxy:
			chrome_options.add_argument(f'--proxy-server={self.proxy}')
		# 浏览器驱动器路径
		chrome_driver_path1 = os.path.join(os.path.dirname(os.path.dirname(__file__)), "static", 'chromedriver.exe')
		chrome_driver_path2 = os.path.join(os.path.dirname(os.path.dirname(__file__)), "static", 'chromedriver1')
		# print(chrome_driver_path)
		server1 = Service(chrome_driver_path1)
		server2 = Service(chrome_driver_path2)

		# 判断系统类型选择浏览器驱动
		os_type = platform.system()
		print(os_type)
		driver = None
		if os_type == 'Darwin':  # Darwin 是 Mac OS X 的系统名称
			print(os_type)
			driver = webdriver.Chrome(options=chrome_options, service=server2)
		elif os_type == 'Windows':
			driver = webdriver.Chrome(options=chrome_options, service=server1)
		else:
			driver = webdriver.Chrome(options=chrome_options)

		driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
			"source": """
                    Object.defineProperty(navigator, 'webdriver', {
                        get: () => undefined
                    });
                    window.navigator.chrome = {
                        runtime: {},
                    };
                    Object.defineProperty(navigator, 'languages', {
                        get: () => ['zh-CN', 'zh']
                    });
                    Object.defineProperty(navigator, 'plugins', {
                        get: () => [1, 2, 3,4,5]
                    });
                """
		})
		# # 打印IP地址
		# ip_element = driver.find_element_by_xpath('//body')
		# print("当前IP地址:", ip_element.text)
		stealth_js_path = os.path.join(os.path.dirname(__file__), 'stealth.min.js')
		if os.path.exists(stealth_js_path):
			with open(stealth_js_path) as f:
				js = f.read()
			driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {"source": js})
		else:
			print(f"Stealth script file not found at {stealth_js_path}")
		# 初始化浏览器
		return driver

	def switch_to_new_tab(self):
		"""
		打开一个新选项卡并切换到新选项卡。

		返回:
			list: 所有窗口句柄。
		"""
		self.driver.execute_script("window.open('about:blank', 'new_tab')")
		handles = self.driver.window_handles
		self.driver.switch_to.window(handles[-1])
		return handles

	def close_other_tabs(self, handles):
		"""
		关闭除当前选项卡外的其他所有选项卡。

		参数:
			handles (list): 所有窗口句柄。
		"""
		for handle in handles[:-1]:
			self.driver.switch_to.window(handle)
			self.driver.close()
		self.driver.switch_to.window(handles[-1])

	def add_cookies(self):
		"""
		将cookies添加到当前的WebDriver会话中。
		"""
		if self.cookies:
			for cookie in self.cookies:
				if cookie['name'] in ['BAIDUID', 'BAIDUID_BFESS', 'BDUSS', 'BDUSS_BFESS']:
					self.driver.add_cookie(cookie)
		# local_storage = json.loads('{"shopManageNavStatus":"0","ugcTelBind":"1","isCdnBosUpload":"1","__bid_n":"191248bb86f566448824f9","wk_rule_tips_key":"1","/commodityManage/documentation":"1","MIAO_ET":"nnkpwro2t3e48yTLW6EijlU9cv4HCDic5EBTk4nsn6WuxOD/ZmkifwicLYaAjjPJ_1722981422761","wkPagesTracker":"{\"urlArr\":[\"https://cuttlefish.baidu.com/shopmis?_wkts_=1722895018385#/commodityManage/documentation\"],\"nodeHistoryList\":[{\"i\":0,\"ta\":0},{\"i\":0,\"ta\":8202},{\"i\":0,\"ta\":12149}],\"nodesMapData\":{\"0\":{\"key\":0,\"parentNodeKey\":-1,\"rootNodeKey\":0,\"channelType\":\"OTHER\",\"logId\":\"3415921566\"}},\"headTs\":1722895018385}","MIAO_LID":"4f4ed431e0d329a9cec761282816f2bec42ae5d8"}')
		# for key, value in local_storage():  # 循环奖值加入到本地秘钥里面
		# 	# 使用 execute_script 执行 JavaScript 代码
		# 	print(f"Setting key '{key}' to '{value}'")
		# 	self.driver.execute_script(f"window.localStorage.setItem('{key}', '{value}')")

	def get_cookies(self):
		"""
		获取当前页面的cookies。

		返回:
			list: 当前页面的cookies列表。
		"""
		try:
			WebDriverWait(self.driver, 6000).until(EC.visibility_of_element_located((By.ID, "s-top-username")))
			return self.driver.get_cookies()
		except Exception as e:
			print("页面元素未出现，无法存储cookie:", e)
			return None

	# 跳转页面，处理弹窗。
	def go_target_url(self):
		"""
		运行整个模拟登录和页面访问的过程。
		"""
		if self.target_type == 0:
			return
		if self.target_type == 1:  # 去文档页面；
			self.driver.get("https://cuttlefish.baidu.com/shopmis#/commodityManage/documentation")
			sleep(2)
			self.driver.execute_script("window.localStorage.setItem('__shop_major_guide_show', 1)")
			self.driver.execute_script("window.localStorage.setItem('isCdnBosUpload', 1)")
			self.driver.execute_script("window.localStorage.setItem('ugcTelBind', 1)")
			self.driver.execute_script("window.localStorage.setItem('wk_rule_tips_key', 1)")
			self.driver.execute_script("window.localStorage.setItem('isCdnBosUpload', 1)")
			self.driver.execute_script(
				"window.localStorage.setItem('target_rule_finished_dialog_close_50dcd8da50e2524de5187ec7', 1)")

			if "passport.baidu.com" in self.driver.current_url:
				print("........登录已经失效，请及时处理.........")
				return
			self.driver.refresh()
			sleep(2)
			self.driver.refresh()
		if self.target_type == 2:  # 去原力任务页面；
			self.driver.get("https://cuttlefish.baidu.com/shopmis#/taskCenter/majorTask")
			sleep(5)
			self.driver.execute_script("window.localStorage.setItem('__shop_major_guide_show', 1)")
			self.driver.execute_script("window.localStorage.setItem('isCdnBosUpload', 1)")
			self.driver.execute_script("window.localStorage.setItem('ugcTelBind', 1)")
			self.driver.execute_script("window.localStorage.setItem('wk_rule_tips_key', 1)")
			self.driver.execute_script("window.localStorage.setItem('isCdnBosUpload', 1)")
			self.driver.execute_script(
				"window.localStorage.setItem('target_rule_finished_dialog_close_50dcd8da50e2524de5187ec7', 1)")
			if "passport.baidu.com" in self.driver.current_url:
				print("........登录已经失效，请及时处理.........")
				return
			self.driver.refresh()
			sleep(10)
			self.driver.refresh()
			sleep(10)
			try:
				close_button = WebDriverWait(self.driver, 10).until(
					EC.element_to_be_clickable(
						(By.CSS_SELECTOR,
						 '#app > div.main-content > section > main > div.major-task > div.target-rule-dialog > div > div > div.el-dialog__footer > span > button'))
				)
				close_button.click()
			except TimeoutException:
				# print("弹出框未解决")
				pass  # 如果没有找到弹出框，继续执行

	def get_task_num(self):
		try:
			rule_button = WebDriverWait(self.driver, 10).until(
				EC.element_to_be_clickable(
					(By.CSS_SELECTOR, '.rule-introduction'))
			)
			rule_button.click()
			sleep(2)
			#获取弹出框.content里面，第8个<p>标签，获取里面的内容。文字内容示例"3.单日上传量：周通过率<50%，日上传量2篇；周通过率<70%，日上传量5篇；周通过率≥70%，日上传量10篇(平台会根据任务量级动态调整上限)"
			#然后提取出"日上传量2篇"，"日上传量5篇"、"日上传量10篇"中的3个数字，返回。
			# 等待弹出框出现
			popup_content = WebDriverWait(self.driver, 10).until(
				EC.presence_of_element_located((By.CSS_SELECTOR, '.el-dialog__body .content'))
			)
			# 找到第8个<p>标签
			p_tags = popup_content.find_elements(By.TAG_NAME, 'p')
			if len(p_tags) >= 8:
				target_p_tag = p_tags[7]
				text_content = target_p_tag.text
				print(text_content)
				pattern = r'日上传量(\d+)篇'
				# 查找所有匹配项
				matches = re.findall(pattern, text_content)
				print(matches)
				# 提取数字
				if len(matches) < 3:
					raise ValueError("Not enough matches found in the input string.")
				# 将匹配到的字符串转换为整数
				num_one, num_two, num_three = map(int, matches[:3])
				return {"num_one":num_one, "num_two":num_two, "num_three":num_three}
			else:
				raise Exception("目标<p>标签未找到")
		except TimeoutException:
			print("超时错误")
			return False
		except Exception as e:
			print(f"发生错误: {e}")
			return False
# 使用示例
if __name__ == "__main__":
	headless = 0
	browser_manager = BrowserManager(is_headless=headless,
	                                 target_type=2)  # ,cookie=cookie_file,  target_url=target_url,proxy=proxy_address
	sleep(1000)
